﻿using System;
using System.Linq;

using Microsoft.Practices.Unity;

using Arquitetura.Architectural.Model;
using Arquitetura.Architectural.DataLayer;
using Arquitetura.Architectural.BusinessLogic.Validation;
using Arquitetura.DataLayer;
using Arquitetura.Model;
using Arquitetura.Common;

namespace Arquitetura.BusinessLogic.Validation
{
    internal enum MaeValidateOperation
    {
        Query,
        Insert,
        Update,
        Delete
    }

    internal class MaeValidation : ValidationBase<Mae, MaeValidateOperation>, IMaeValidation
    {
        #region Atributo(s)
        private readonly IPessoaRepository m_pessoaRepository;
        #endregion Atributo(s)

        #region Contrutor(es)
        [InjectionConstructor]
        public MaeValidation(IPessoaRepository pessoaRepository)
            : base()
        {
            m_pessoaRepository = pessoaRepository;
        }
        #endregion Contrutor(es)

        #region Método(s)
        protected override void ValidateDataAdvancedRules()
        {
            switch (Operation)
            {
                case MaeValidateOperation.Query:
                    break;

                case MaeValidateOperation.Insert:
                    ValidarCPFValido();
                    break;

                case MaeValidateOperation.Update:
                    ValidarCPFValido();
                    break;

                case MaeValidateOperation.Delete:
                    break;

                default:
                    break;
            }
        }

        protected override void ValidateBusinessRules()
        {
            switch (Operation)
            {
                case MaeValidateOperation.Query:
                    ValidarExistencia();
                    break;

                case MaeValidateOperation.Insert:
                    ValidarCPFUnico();
                    break;

                case MaeValidateOperation.Update:
                    ValidarExistencia();
                    ValidarCPFUnico();
                    break;

                case MaeValidateOperation.Delete:
                    ValidarExistencia();
                    break;

                default:
                    break;
            }
        }

        private void ValidarExistencia()
        {
            Result<IQueryable<Mae>> result = m_pessoaRepository.SelectMae();
            if (result.Success)
            {
                if (!result.Returned.Where(mae => mae.Id == Target.Id).Any())
                {
                    ResultMessage messagem = new ResultMessage();
                    messagem.EntityName = "Mae";
                    messagem.EntityField = "Id";
                    messagem.Informations.Add("Registro da Mãe do Aluno não encontrado");
                    AddResult(false, messagem);
                }
            }
            else
            {
                AddResults(result);
            }
        }

        private void ValidarCPFValido()
        {
            if (!Valida.ValidaCPF(Target.CPF))
            {
                ResultMessage messagem = new ResultMessage();
                messagem.EntityName = "Mae";
                messagem.EntityField = "CPF";
                messagem.Informations.Add("Favor preencher o campo CPF com um valor válido");
                AddResult(false, messagem);
            }
        }

        private void ValidarCPFUnico()
        {
            Result<IQueryable<Mae>> result = m_pessoaRepository.SelectMae();
            if (result.Success)
            {
                switch (Operation)
                {
                    case MaeValidateOperation.Insert:
                        if (result.Returned.Where(mae => mae.CPF.Equals(Target.CPF,
                            StringComparison.InvariantCultureIgnoreCase)).Any())
                        {
                            ResultMessage messagem = new ResultMessage();
                            messagem.EntityName = "Mae";
                            messagem.EntityField = "CPF";
                            messagem.Informations.Add("Já existe outra mãe de aluno com CPF informado");
                            AddResult(false, messagem);
                        } break;

                    case MaeValidateOperation.Update:
                        if (result.Returned.Where(alu => (alu.Id != alu.Id) && (alu.CPF.Equals(
                            Target.CPF, StringComparison.InvariantCultureIgnoreCase))).Any())
                        {
                            ResultMessage messagem = new ResultMessage();
                            messagem.EntityName = "Aluno";
                            messagem.EntityField = "CPF";
                            messagem.Informations.Add("Já existe outra mãe de aluno com CPF informado");
                            AddResult(false, messagem);
                        } break;

                    default:
                        break;
                }
            }
            else
            {
                AddResults(result);
            }
        }
        #endregion Método(s)
    }
}
